#include <windows.h>
#include <stdio.h>

HANDLE gDoneEvent;

VOID CALLBACK TimerRoutine(PVOID lpParam, BOOLEAN TimerOrWaitFired)
{
	if (lpParam == NULL) {
		printf("TimerRoutine lpParam is NULL\n");
	} else {
		// lpParam points to the argument; in this case it is an int

		printf("Timer routine called. Parameter is %d.\n", *(int*)lpParam);
		if (TimerOrWaitFired) {
			printf("The wait timed out.\n");
		} else {
			printf("The wait event was signalled.\n");
		}
	}

	SetEvent(gDoneEvent);
}

int main()
{
	HANDLE hTimer = NULL;
	HANDLE hTimerQueue = NULL;
	int arg = 123;

	// Use an event object to track the TimerRoutine execution
	gDoneEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
	if (NULL == gDoneEvent) {
		printf("CreateEvent failed (%lu)\n", GetLastError());
		return 1;
	}

	// Create the timer queue.
	hTimerQueue = CreateTimerQueue();
	if (NULL == hTimerQueue) {
		printf("CreateTimerQueue failed (%lu)\n", GetLastError());
		return 2;
	}

	// Set a timer to call the timer routine in 10 seconds.
	if (!CreateTimerQueueTimer(&hTimer, hTimerQueue,(WAITORTIMERCALLBACK)TimerRoutine, &arg , 0, 100, 0)) {
		printf("CreateTimerQueueTimer failed (%lu)\n", GetLastError());
		return 3;
	}

	printf("Call timer routine in 100mS...\n");

	for (int i=0; i<10; i++) {
		Sleep(1000);
		printf("sleep exec %d\n",i);
	}

	// Wait for the timer-queue thread to complete using an event
	// object. The thread will signal the event at that time.

	if (WaitForSingleObject(gDoneEvent, INFINITE) != WAIT_OBJECT_0)
		printf("WaitForSingleObject failed (%lu)\n", GetLastError());

	CloseHandle(gDoneEvent);

	// Delete all timers in the timer queue.
	if (!DeleteTimerQueue(hTimerQueue))
		printf("DeleteTimerQueue failed (%lu)\n", GetLastError());

	return 0;
}
